<template>
  <div class="canvas-editor">
    <div class="toolbar">
      <van-button @click="undo" :disabled="!canUndo">撤销</van-button>
      <van-button @click="redo" :disabled="!canRedo">重做</van-button>
      <van-uploader :after-read="handleFileUpload" accept="image/*">
        <van-button>上传图片</van-button>
      </van-uploader>
    </div>
    <div class="canvas-container">
      <canvas ref="canvasRef"></canvas>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch } from "vue";
import { useHistory } from "@/hooks/useCanvasHistory";

interface ImageItem {
  id: string;
  x: number;
  y: number;
  width: number;
  height: number;
  rotation: number;
  scale: number;
  flipX: boolean;
  flipY: boolean;
  src: string;
}

const canvasRef = ref<HTMLCanvasElement | null>(null);
const ctx = ref<CanvasRenderingContext2D | null>(null);
const images = ref<ImageItem[]>([]);
const selectedImageId = ref<string | null>(null);
const isDragging = ref(false);
const dragOffset = ref({ x: 0, y: 0 });

const {
  state: historyState,
  pushState,
  undo,
  redo,
  canUndo,
  canRedo,
} = useHistory<ImageItem[]>([]);
// 添加状态同步
watch(historyState, (newState) => {
    images.value = [...newState];
    redrawCanvas();
  }, { deep: true });
// 初始化Canvas
onMounted(() => {
  if (canvasRef.value) {
    ctx.value = canvasRef.value.getContext("2d");
    resizeCanvas();
    window.addEventListener("resize", resizeCanvas);
  }
});
// 修改所有操作函数，确保使用pushState更新状态
const pushStateAndRedraw = (newImages: ImageItem[]) => {
    pushState([...newImages]);
  };
// 调整Canvas大小
const resizeCanvas = () => {
  if (canvasRef.value) {
    const container = canvasRef.value.parentElement;
    if (container) {
      canvasRef.value.width = container.clientWidth;
      canvasRef.value.height = container.clientHeight;
        // 增大画布尺寸为父容器的1.5倍
        // canvasRef.value.width = container.clientWidth * 1.5;
        // canvasRef.value.height = container.clientHeight * 1.5;
      redrawCanvas();
    }
  }
};

// 处理图片上传
const handleFileUpload = (
  fileInfo: File | { file: File } | { file: File }[]
) => {
  // 处理Vant Uploader传递的不同参数格式
  let file: File;

  if (Array.isArray(fileInfo)) {
    // 多文件上传情况
    file = fileInfo[0].file;
  } else if (fileInfo instanceof File) {
    // 直接传递File对象
    file = fileInfo;
  } else {
    // 传递了{file: File}对象
    file = fileInfo.file;
  }

  const reader = new FileReader();
  reader.onload = (e) => {
    const img = new Image();
    img.onload = () => {
      if (!canvasRef.value) return;

      // 计算缩放比例，使图片适应画布
      const canvasWidth = canvasRef.value.width;
      const canvasHeight = canvasRef.value.height;
      const imgRatio = img.width / img.height;
      const canvasRatio = canvasWidth / canvasHeight;

      let displayWidth, displayHeight;

      if (imgRatio > canvasRatio) {
        // 图片比画布更宽
        displayWidth = canvasWidth * 0.8; // 保留边距
        displayHeight = displayWidth / imgRatio;
      } else {
        // 图片比画布更高
        displayHeight = canvasHeight * 0.8; // 保留边距
        displayWidth = displayHeight * imgRatio;
      }

      // 计算居中位置
      const x = (canvasWidth - displayWidth) / 2;
      const y = (canvasHeight - displayHeight) / 2;

      const newImage: ImageItem = {
        id: Date.now().toString(),
        x,
        y,
        width: displayWidth,
        height: displayHeight,
        rotation: 0,
        scale: 1,
        flipX: false,
        flipY: false,
        src: e.target?.result as string,
      };
      images.value.push(newImage);
      pushState([...images.value]);
      redrawCanvas();
    };
    img.onerror = () => console.error("图片加载失败");
    img.src = e.target?.result as string;
  };
  reader.onerror = () => console.error("文件读取失败");
  reader.readAsDataURL(file);
};

// 重绘Canvas
const redrawCanvas = () => {
  if (!ctx.value || !canvasRef.value) return;

  ctx.value.clearRect(0, 0, canvasRef.value.width, canvasRef.value.height);

  images.value.forEach((img) => {
    drawImage(img);

    // 绘制选中框
    if (img.id === selectedImageId.value) {
      drawSelectionBox(img);
    }
  });
};

// 绘制图片
const drawImage = (img: ImageItem) => {
  if (!ctx.value) return;

  ctx.value.save();
  ctx.value.translate(img.x + img.width / 2, img.y + img.height / 2);
  ctx.value.rotate((img.rotation * Math.PI) / 180);
  ctx.value.scale(
    img.scale * (img.flipX ? -1 : 1),
    img.scale * (img.flipY ? -1 : 1)
  );

  const imageObj = new Image();
  imageObj.src = img.src;
  ctx.value.drawImage(
    imageObj,
    -img.width / 2,
    -img.height / 2,
    img.width,
    img.height
  );

  ctx.value.restore();
};

// // 绘制选中框
// const drawSelectionBox = (img: ImageItem) => {
//   if (!ctx.value) return;

//   const padding = 10;
//   const boxWidth = img.width * img.scale + padding * 2;
//   const boxHeight = img.height * img.scale + padding * 2;

//   // 绘制虚线框
//   ctx.value.save();
//   ctx.value.setLineDash([5, 5]);
//   ctx.value.strokeStyle = "#1890ff";
//   ctx.value.lineWidth = 2;
//   ctx.value.strokeRect(img.x - padding, img.y - padding, boxWidth, boxHeight);
//   ctx.value.restore();

//   // 绘制控制按钮
//   // 绘制控制按钮 - 修正坐标计算
//   drawControlButton(img, "delete", img.x - padding - 15, img.y - padding - 15);
//   drawControlButton(img, "rotate", img.x + boxWidth - padding - 15, img.y - padding - 15);
//   drawControlButton(img, "scale", img.x + boxWidth - padding - 15, img.y + boxHeight - padding - 15);
//   drawControlButton(img, "flip", img.x - padding - 15, img.y + boxHeight - padding - 15);
// };

// 新增按钮位置映射
const buttonMap = ref(new Map<string, string>());
// 绘制选中框
const drawSelectionBox = (img: ImageItem) => {
    if (!ctx.value) return;
  
    const padding = 10;
    ctx.value.save();
    
    // 应用与图片相同的变换
    ctx.value.translate(img.x + img.width / 2, img.y + img.height / 2);
    ctx.value.rotate((img.rotation * Math.PI) / 180);
    ctx.value.scale(img.flipX ? -1 : 1, img.flipY ? -1 : 1);
  
    // 计算缩放后尺寸
    const scaledWidth = img.width * img.scale;
    const scaledHeight = img.height * img.scale;
    
    // 绘制虚线框（在变换后的坐标系中）
    ctx.value.setLineDash([5, 5]);
    ctx.value.strokeStyle = "#1890ff";
    ctx.value.lineWidth = 2;
    ctx.value.strokeRect(
      -scaledWidth / 2 - padding,
      -scaledHeight / 2 - padding,
      scaledWidth + padding * 2,
      scaledHeight + padding * 2
    );
  
    // 绘制控制按钮（保留类型参数）
    const drawButton = (type: string, x: number, y: number) => {
    //   ctx.value!.beginPath();
    //   ctx.value!.arc(x, y, 10, 0, Math.PI * 2);
    //   ctx.value!.fill();

     ctx.value!.save(); // 保存画布状态
    ctx.value!.fillStyle = "#1890ff"; // 恢复按钮颜色
    
    // 绘制按钮背景
    ctx.value!.beginPath();
    ctx.value!.arc(x, y, 10, 0, Math.PI * 2);
    ctx.value!.fill();

    // 绘制按钮图标（恢复白色文字）
    ctx.value!.fillStyle = "#fff";
    ctx.value!.font = "12px Arial";
    ctx.value!.textAlign = "center";
    ctx.value!.textBaseline = "middle";
    
    // 根据类型添加符号
    switch(type) {
      case "delete": ctx.value!.fillText("×", x, y); break;
      case "rotate": ctx.value!.fillText("↻", x, y); break;
      case "scale": ctx.value!.fillText("↔", x, y); break;
      case "flip": ctx.value!.fillText("⇄", x, y); break;
    }

    ctx.value!.restore(); // 恢复画布状态
      
      // 添加按钮类型到位置映射
      const screenPos = {
        x: x + img.x + img.width/2,
        y: y + img.y + img.height/2
      };
      buttonMap.value.set(JSON.stringify(screenPos), type);
    };
  
    // 按钮位置计算（保持原有类型顺序）
    const halfW = scaledWidth / 2 + padding;
    const halfH = scaledHeight / 2 + padding;
    
    // // 删除按钮（左上）
    // drawButton("delete", -halfW - 5, -halfH - 5);
    // // 旋转按钮（右上）
    // drawButton("rotate", halfW + 5, -halfH - 5);
    // // 缩放按钮（右下）
    // drawButton("scale", halfW + 5, halfH + 5);
    // // 翻转按钮（左下）
    // drawButton("flip", -halfW - 5, halfH + 5);

        // 按钮位置计算（考虑翻转状态）
        const flipXSign = img.flipX ? -1 : 1;
        const flipYSign = img.flipY ? -1 : 1;

        // 计算基础偏移量
        const baseX = scaledWidth / 2 + padding;
        const baseY = scaledHeight / 2 + padding;

      // 绘制按钮（调整后的计算方式）
    //   drawButton("delete", -baseX * flipXSign - 5, -baseY * flipYSign - 5);
    //   drawButton("rotate", baseX * flipXSign - 5, -baseY * flipYSign - 5);
    //   drawButton("scale", baseX * flipXSign - 5, baseY * flipYSign - 5);
    //   drawButton("flip", -baseX * flipXSign - 5, baseY * flipYSign - 5);

        // 绘制按钮（调整后的计算方式）
        const buttonSize = 20; // 按钮大小
        const buttonOffset = 5; // 按钮偏移量

     // 计算按钮位置（考虑翻转状态）
     drawButton("delete", 
     -scaledWidth/2 - padding - buttonSize/2 - buttonOffset, 
     -scaledHeight/2 - padding - buttonSize/2 - buttonOffset
   );
   drawButton("rotate", 
     scaledWidth/2 + padding + buttonSize/2 + buttonOffset, 
     -scaledHeight/2 - padding - buttonSize/2 - buttonOffset
   );
   drawButton("scale", 
     scaledWidth/2 + padding + buttonSize/2 + buttonOffset, 
     scaledHeight/2 + padding + buttonSize/2 + buttonOffset
   );
   drawButton("flip", 
     -scaledWidth/2 - padding - buttonSize/2 - buttonOffset, 
     scaledHeight/2 + padding + buttonSize/2 + buttonOffset
   );
  
    ctx.value.restore();
  };

// 绘制控制按钮
const drawControlButton = (
  img: ImageItem,
  type: string,
  x: number,
  y: number
) => {
  if (!ctx.value) return;

  ctx.value.save();
  ctx.value.fillStyle = "#1890ff";
  ctx.value.beginPath();
  ctx.value.arc(x, y, 10, 0, Math.PI * 2);
  ctx.value.fill();

  // 这里可以添加按钮图标
  ctx.value.fillStyle = "#fff";
  ctx.value.font = "12px Arial";
  ctx.value.textAlign = "center";
  ctx.value.textBaseline = "middle";

  switch (type) {
    case "delete":
      ctx.value.fillText("×", x, y);
      break;
    case "rotate":
      ctx.value.fillText("↻", x, y);
      break;
    case "scale":
      ctx.value.fillText("↔", x, y);
      break;
    case "flip":
      ctx.value.fillText("⇄", x, y);
      break;
  }

  ctx.value.restore();
};

// 鼠标事件处理
// const handleCanvasMouseDown = (e: MouseEvent) => {
//   if (!canvasRef.value) return;

//   const rect = canvasRef.value.getBoundingClientRect();
//   const x = e.clientX - rect.left;
//   const y = e.clientY - rect.top;

//   // 检查是否点击了控制按钮
//   const clickedImage = images.value.find((img) => {
//     if (img.id === selectedImageId.value) {
//       const padding = 10;
//       const boxWidth = img.width * img.scale + padding * 2;
//       const boxHeight = img.height * img.scale + padding * 2;

//       // 删除按钮 (左上角)
//       if (isPointInControlButton(x, y, img.x - padding - 15, img.y - padding - 15)) {
//         deleteImage(img.id);
//         return true;
//       }

//       // 旋转按钮 (右上角)
//       if (isPointInControlButton(x, y, img.x + boxWidth - padding - 15, img.y - padding - 15)) {
//         startRotate(img.id, x, y);
//         return true;
//       }

//       // 缩放按钮 (右下角)
//       if (isPointInControlButton(x, y, img.x + boxWidth - padding - 15, img.y + boxHeight - padding - 15)) {
//         startScale(img.id, x, y);
//         return true;
//       }

//       // 翻转按钮 (左下角)
//       if (isPointInControlButton(x, y, img.x - padding - 15, img.y + boxHeight - padding - 15)) {
//         flipImage(img.id);
//         return true;
//       }
//     }
//     return false;
//   });

//   if (clickedImage) return;

//   // 检查是否点击了图片
//   const clickedImg = images.value.find((img) => {
//     return isPointInImage(x, y, img);
//   });

//   if (clickedImg) {
//     selectedImageId.value = clickedImg.id;
//     isDragging.value = true;
//     dragOffset.value = {
//       x: x - clickedImg.x,
//       y: y - clickedImg.y,
//     };
//   } else {
//     selectedImageId.value = null;
//   }

//   redrawCanvas();
// };

const handleCanvasMouseDown = (e: MouseEvent) => {
    if (!canvasRef.value) return;
  
    const rect = canvasRef.value.getBoundingClientRect();
    const clickX = e.clientX - rect.left;
    const clickY = e.clientY - rect.top;
  
    // 检查是否点击了控制按钮
    // 检查按钮点击（新增坐标转换逻辑）
    for (const [key, type] of buttonMap.value) {
      const pos = JSON.parse(key);
      const distance = Math.sqrt(Math.pow(clickX - pos.x, 2) + Math.pow(clickY - pos.y, 2));
      if (distance < 15) {
        const img = images.value.find(img => img.id === selectedImageId.value);
        if (!img) return;
  
        // 根据翻转状态调整功能逻辑
        const flipXSign = img.flipX ? -1 : 1;
        const flipYSign = img.flipY ? -1 : 1;
        switch(type) {
          case "delete": 
            deleteImage(img.id);
            break;
          case "rotate":
            startRotate(img.id, clickX, clickY);
            break;
          case "scale":
            startScale(img.id, clickX, clickY);
            break;
          case "flip":
            // 直接切换翻转状态
            img.flipX = !img.flipX;
            buttonMap.value.clear();
            redrawCanvas();
            pushStateAndRedraw([...images.value]);
            // flipImage(img.id);
            break;
        }
        return;
      }
    }
  
  //   if (clickedImage) return;
  
    // 检查是否点击了图片
    const clickedImg = images.value.find((img) => {
      return isPointInImage(clickX, clickY, img);
    });
  
    if (clickedImg) {
      selectedImageId.value = clickedImg.id;
      isDragging.value = true;
      dragOffset.value = {
        x: clickX - clickedImg.x,
        y: clickY - clickedImg.y,
      };
    } else {
      selectedImageId.value = null;
    }
  
    redrawCanvas();
  };
// 判断点是否在控制按钮内
const isPointInControlButton = (x: number, y: number, btnX: number, btnY: number) => {
    // const distance = Math.sqrt(Math.pow(x - (img.x + btnX), 2) + Math.pow(y - (img.y + btnY), 2));
    // 直接使用传入的按钮坐标(已经是绝对坐标)
    // const distance = Math.sqrt(Math.pow(x - btnX, 2) + Math.pow(y - btnY, 2));
    const distance = Math.sqrt(Math.pow(x - btnX, 2) + Math.pow(y - btnY, 2));
    return distance < 15; // 按钮半径
  };
// 判断点是否在图片内
const isPointInImage = (x: number, y: number, img: ImageItem) => {
  // 转换坐标到图片的局部坐标系
  const dx = x - (img.x + img.width / 2);
  const dy = y - (img.y + img.height / 2);

  // 考虑旋转
  const angle = (-img.rotation * Math.PI) / 180;
  const rotatedX = dx * Math.cos(angle) - dy * Math.sin(angle);
  const rotatedY = dx * Math.sin(angle) + dy * Math.cos(angle);

  // 检查是否在图片范围内
  return (
    Math.abs(rotatedX) <= (img.width / 2) * img.scale &&
    Math.abs(rotatedY) <= (img.height / 2) * img.scale
  );
};

// 开始旋转
const startRotate = (id: string, startX: number, startY: number) => {
  const img = images.value.find((img) => img.id === id);
  if (!img) return;
    
  const centerX = img.x + img.width / 2;
  const centerY = img.y + img.height / 2;

  const handleMouseMove = (e: MouseEvent) => {
    if (!canvasRef.value) return;

    const rect = canvasRef.value.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;

    const angle = (Math.atan2(y - centerY, x - centerX) * 180) / Math.PI;
    img.rotation = angle;
    redrawCanvas();
  };

  const handleMouseUp = () => {
    window.removeEventListener("mousemove", handleMouseMove);
    window.removeEventListener("mouseup", handleMouseUp);
    // pushState([...images.value]);
    pushStateAndRedraw([...images.value]);
  };

  window.addEventListener("mousemove", handleMouseMove);
  window.addEventListener("mouseup", handleMouseUp);
};

// 开始缩放
const startScale = (id: string, startX: number, startY: number) => {
  const img = images.value.find((img) => img.id === id);
  if (!img) return;

  const centerX = img.x + img.width / 2;
  const centerY = img.y + img.height / 2;
  const initialDistance = Math.sqrt(Math.pow(startX - centerX, 2) + Math.pow(startY - centerY, 2));
  const initialScale = img.scale;
  const handleMouseMove = (e: MouseEvent) => {
    if (!canvasRef.value) return;

    const rect = canvasRef.value.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;

    // const currentDistance = Math.sqrt(
    //   Math.pow(x - (img.x + img.width / 2), 2) +
    //     Math.pow(y - (img.y + img.height / 2), 2)
    // );

    const currentDistance = Math.sqrt(Math.pow(x - centerX, 2) + Math.pow(y - centerY, 2));
    img.scale = Math.max(0.1, initialScale * (currentDistance / initialDistance));

    img.scale = Math.max(0.1, currentDistance / initialDistance);
    redrawCanvas();
  };

  const handleMouseUp = () => {
    window.removeEventListener("mousemove", handleMouseMove);
    window.removeEventListener("mouseup", handleMouseUp);
    // pushState([...images.value]);
    pushStateAndRedraw([...images.value]);
  };

  window.addEventListener("mousemove", handleMouseMove);
  window.addEventListener("mouseup", handleMouseUp);
};

// 翻转图片
const flipImage = (id: string) => {
  const img = images.value.find((img) => img.id === id);
  if (!img) return;

  img.flipX = !img.flipX;
  buttonMap.value.clear(); // 清除旧的按钮映射
  redrawCanvas();
//   pushState([...images.value]);
pushStateAndRedraw([...images.value]);
};

// 删除图片
const deleteImage = (id: string) => {
    const newImages = images.value.filter((img) => img.id !== id);
    if (selectedImageId.value === id) {
      selectedImageId.value = null;
    }
    pushStateAndRedraw(newImages);
};

// 拖拽图片
const handleCanvasMouseMove = (e: MouseEvent) => {
  if (!isDragging.value || !canvasRef.value || !selectedImageId.value) return;

  const rect = canvasRef.value.getBoundingClientRect();
  const x = e.clientX - rect.left;
  const y = e.clientY - rect.top;

  const img = images.value.find((img) => img.id === selectedImageId.value);
  if (img) {
    img.x = x - dragOffset.value.x;
    img.y = y - dragOffset.value.y;
    redrawCanvas();
  }
};

const handleCanvasMouseUp = () => {
  if (isDragging.value) {
    isDragging.value = false;
    // pushState([...images.value]);
    pushStateAndRedraw([...images.value]);
  }
};

// 初始化事件监听
onMounted(() => {
  if (canvasRef.value) {
    canvasRef.value.addEventListener("mousedown", handleCanvasMouseDown);
    canvasRef.value.addEventListener("mousemove", handleCanvasMouseMove);
    canvasRef.value.addEventListener("mouseup", handleCanvasMouseUp);
  }
});
</script>

<style scoped>
.canvas-editor {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.toolbar {
  padding: 10px;
  display: flex;
  gap: 10px;
  background: #f5f5f5;
}

.canvas-container {
  flex: 1;
  position: relative;
  overflow: hidden;
  min-height: 500px; /* 设置最小高度 */
}

canvas {
  width: 100%;
  height: 100%;
  background: white;
  border: 1px solid #ddd;
}
</style>
